#pragma once
#include <memory>
#include <thread>
#include <sstream>

#include "Level.h"
#include "Util.h"

namespace mylog
{
    struct LogMessage
    {
        using ptr = std::shared_ptr<LogMessage>;
        LogMessage() = default;
        LogMessage(LogLevel::value level, 
                   const std::string& filename, 
                   size_t line, 
                   const std::string& loggerName, 
                   const std::string& payload)
            : level_(level)
            , filename_(filename)
            , line_(line)
            , logger_name_(loggerName)
            , payload_(payload)
            , ctime_(Util::Date::Now())
            , tid_(std::this_thread::get_id())
        {
        }

        std::string format()
        {
            std::stringstream ss;
            ss << tid_;
            std::string thread_id = ss.str();
            struct tm t;
            localtime_r(&ctime_, &t);
            char buf[128];
            strftime(buf, sizeof(buf), "%H:%M:%S", &t);
            // [时间] [线程ID] [日志等级] [日志器名称] [文件名:行号]  消息
            std::string ret = '[' + std::string(buf) + ']';
            ret += " [" + thread_id + ']';
            ret += " [" + std::string(LogLevel::ToString(level_))+ ']';
            ret += " [" + logger_name_ + ']';
            ret += " [" + filename_ + ":" + std::to_string(line_) + "]\t" + payload_ + "\n";
            return ret;
        }

        LogLevel::value level_;     // 日志等级
        std::string filename_;      // 日志记录时所在文件
        size_t line_;               // 日志记录时所在文件的行号
        std::string logger_name_;   // 进行日志记录的Logger名称
        std::string payload_;       // 日志记录的信息
        time_t ctime_;              // 日志记录发生时间的时间戳
        std::thread::id tid_;       // 日志记录所在线程
    };
} // namespace log